home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / visulztn / saoimage / saoimage.lha / editdraw.c < prev    next >
C/C++ Source or Header  |  1991-01-05  |  10KB  |  350 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    editdraw.c (Editor Draw)
  6.  * Purpose:    Draw the edited line in the popup window
  7.  * Subroutine:    set_edit_draw_func()        returns: void
  8.  * Subroutine:    unset_edit_draw_func()        returns: void
  9.  * Subroutine:    draw_new_string()        returns: void
  10.  * Subroutine:    redraw_edit_string()        returns: void
  11.  * Subroutine:    draw_edit_string()        returns: void
  12.  * Subroutine:    draw_edit_cursor()        returns: void
  13.  * Xlib calls:    XClearArea(), XDrawImageString(), XPutImage()
  14.  * Copyright:    1989, 1990 Smithsonian Astrophysical Observatory
  15.  *        You may do anything you like with this file except remove
  16.  *        this copyright.  The Smithsonian Astrophysical Observatory
  17.  *        makes no representations about the suitability of this
  18.  *        software for any purpose.  It is provided "as is" without
  19.  *        express or implied warranty.
  20.  * Modified:    {0} Michael VanHilst    initial version          4 July 1989
  21.  *        {1} MVH ability to use specified func and mask       1 Jan 1991
  22.  *        {n} <who> -- <does what> -- <when>
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <X11/Xlib.h>
  27. #include "hfiles/define.h"    /*  Define DONT_CARE, U_DONT_CARE  */
  28. #include "hfiles/edit.h"
  29.  
  30.  
  31. /*  Flag to switch between default drawing and client mask and function  */
  32. int basic_func = 1;
  33. /*  Values used to draw with GC func other than GXcopy to AllPlanes  */
  34. int editor_func = GXcopy;
  35. unsigned long editor_mask = AllPlanes;
  36.  
  37. static char left_bits[7] = { 0x20, 0x30, 0x38, 0x3c, 0x38, 0x30, 0x20 };
  38. static char right_bits[7] = { 0x04, 0x0c, 0x1c, 0x3c, 0x1c, 0x0c, 0x04 };
  39.  
  40. static XImage ximage = {
  41.   8, 7, 0, XYBitmap, NULL, LSBFirst, 8, LSBFirst, 8, 1, 1, 0 };
  42.  
  43. /* define offsets for drawing overflow marks */
  44. #define MARK_LEFT 10
  45. #define MARK_RIGHT 2
  46. #define MARK_Y 8
  47.  
  48.  
  49. #ifdef ANSIC
  50. /*  Exported declarations must be centralized before ANSI C can be used  */
  51.  
  52. void        set_edit_draw_func(    int func, unsigned long mask);
  53. void        unset_edit_draw_func();
  54. void        draw_new_string(    EditStruct *edit, int clear);
  55. void        redraw_edit_string(    EditStruct *edit);
  56. void        draw_edit_string(    EditStruct *edit, int first_char,
  57.                     int first_x, int nchars);
  58. void        draw_edit_cursor(    EditStruct *edit, int erase);
  59. static void    mark_left(        EditStruct *edit, GC gc);
  60. static void    clear_left(        EditStruct *edit);
  61. static void    mark_right(        EditStruct *edit, GC gc);
  62. static void    clear_right(        EditStruct *edit);
  63. static void    clear_area(        EditStruct *edit, int x, int y,
  64.                     int width, int height);
  65.  
  66. #else
  67.  
  68.   void draw_edit_string(), draw_edit_cursor();
  69.   GC set_text_gc();
  70.   static void clear_area();
  71.   static void mark_left(), clear_left(), mark_right(), clear_right();
  72.  
  73. #endif
  74.  
  75.  
  76. /*  Subroutine:    set_edit_draw_func
  77.  *  Purpose:    Set draw func to func and mask
  78.  */
  79. #ifdef ANSIC
  80. void set_edit_draw_func ( int func, unsigned long mask )
  81. #else
  82. void set_edit_draw_func ( func, mask )
  83.      int func;
  84.      unsigned long mask;
  85. #endif
  86. {
  87.   editor_func = func;
  88.   editor_mask = mask;
  89.   basic_func = 0;
  90. }
  91.  
  92.  
  93. /*  Subroutine:    unset_edit_draw_func
  94.  *  Purpose:    Unset draw func to func and mask
  95.  */
  96. void unset_edit_draw_func()
  97. {
  98.   editor_func = GXcopy;
  99.   editor_mask = AllPlanes;
  100.   basic_func = 1;
  101. }
  102.  
  103.  
  104. /*  Subroutine:    draw_new_string
  105.  *  Purpose:    Draw a string for the first time (new window or new string)
  106.  */
  107. #ifdef ANSIC
  108. void draw_new_string ( EditStruct *edit, int clear )
  109. #else
  110. void draw_new_string ( edit, clear )
  111.      EditStruct *edit;
  112.      int clear;        /* i: clear-window-before-drawing */
  113. #endif
  114. {
  115.   int first_char, first_x, nchars, i, len;
  116.  
  117.   first_char = 0;
  118.   first_x = 0;
  119.   if( edit->pixlen[edit->char_cnt + 2] > edit->max_pixlen ) {
  120.     edit->oversize = 1;
  121.     len = edit->pixlen[edit->char_cnt + 2];
  122.     for( i = 0;
  123.     (i <= edit->char_cnt) && (len - edit->pixlen[i]) > edit->max_pixlen;
  124.     i++ );
  125.     first_char = i;
  126.     nchars = edit->char_cnt + 1 - i;
  127.   } else {
  128.     edit->oversize = 0;
  129.     nchars = edit->char_cnt + 1;
  130.   }
  131.   edit->left_mark_drawn = 0;
  132.   edit->right_mark_drawn = 0;
  133.   edit->last_x_shown = 0;
  134.   edit->first_char_shown = first_char;
  135.   edit->active_position = edit->char_cnt;
  136.   /*  Draw if the mask is not 0  */
  137.   if( editor_mask ) {
  138.     if( clear )
  139.       clear_area(edit, edit->x - MARK_LEFT, edit->area_y,
  140.          edit->max_pixlen + MARK_LEFT + MARK_RIGHT + 8,
  141.          edit->area_height);
  142.     draw_edit_string(edit, first_char, first_x, nchars);
  143.   }
  144. }
  145.  
  146.  
  147. /*  Subroutine:    redraw_edit_string
  148.  *  Purpose:    Redraw the string as it was after a popup window expose event
  149.  */
  150. #ifdef ANSIC
  151. void redraw_edit_string ( EditStruct *edit )
  152. #else
  153. void redraw_edit_string ( edit )
  154.      EditStruct *edit;
  155. #endif
  156. {
  157.   int first_char, first_x, nchars;
  158.  
  159.   edit->left_mark_drawn = 0;
  160.   edit->right_mark_drawn = 0;
  161.   first_x = 0;
  162.   first_char = edit->first_char_shown;
  163.   nchars = edit->last_char_shown + 1 - first_char;
  164.   draw_edit_string(edit, first_char, first_x, nchars);
  165. }
  166.  
  167.  
  168. /*  Subroutine:    draw_edit_string
  169.  *  Purpose:    Display a section of string and the text cursor
  170.  *  Xlib calls:    XDrawImageString()
  171.  */
  172. #ifdef ANSIC
  173. void draw_edit_string ( EditStruct *edit, int first_char,
  174.             int first_x, int nchars )
  175. #else
  176. void draw_edit_string ( edit, first_char, first_x, nchars )
  177.      EditStruct *edit;
  178.      int first_char;
  179.      int first_x;
  180.      int nchars;
  181. #endif
  182. {
  183.   int x;
  184.   GC gc;
  185.  
  186.   /*  Don't draw if the mask is 0  */
  187.   if( editor_mask == 0 ) {
  188.     edit->last_x_shown = edit->pixlen[first_char + nchars]
  189.       - edit->pixlen[edit->first_char_shown];
  190.     edit->last_char_shown = first_char + nchars - 1;
  191.     return;
  192.   }
  193.   gc = set_text_gc(edit->font, edit->foreground, edit->background,
  194.            editor_func, editor_mask);
  195.   /*  Stencil chars if tracking the string or not having a background  */
  196.   if( (editor_func == GXxor) ||
  197.       (edit->background == U_DONT_CARE) ||
  198.       (edit->background == edit->foreground) )
  199.     XDrawString(edit->display, edit->ID, gc, edit->x + first_x, edit->y,
  200.         &(edit->string[first_char]), nchars);
  201.   else
  202.     XDrawImageString(edit->display, edit->ID, gc, edit->x + first_x, edit->y,
  203.              &(edit->string[first_char]), nchars);
  204.   /*  Calculate x offset at end of string  */
  205.   x = edit->pixlen[first_char + nchars] - edit->pixlen[edit->first_char_shown];
  206.   /*  Clean up after end of string  */
  207.   if( editor_mask && (x < edit->last_x_shown) )
  208.     clear_area(edit, edit->x + x, edit->area_y,
  209.            edit->last_x_shown - x, edit->area_height);
  210.   edit->last_x_shown = x;
  211.   edit->last_char_shown = first_char + nchars - 1;
  212.   /*  Don't draw anything is mask is 0  */
  213.   if( editor_mask == 0 )
  214.     return;
  215.   /*  Mark line truncation at either end  */
  216.   if( edit->oversize || edit->left_mark_drawn || edit->right_mark_drawn ) {
  217.     if( edit->first_char_shown > 0 ) {
  218.       if( !edit->left_mark_drawn ) {
  219.     mark_left(edit, gc);
  220.     edit->left_mark_drawn = 1;
  221.       }
  222.     } else if( edit->left_mark_drawn ) {
  223.       clear_left(edit);
  224.       edit->left_mark_drawn = 0;
  225.     }
  226.     if( edit->char_cnt > edit->last_char_shown ) {
  227.       if( !edit->right_mark_drawn ) {
  228.     mark_right(edit, gc);
  229.     edit->right_mark_drawn = 1;
  230.       }
  231.     } else if( edit->right_mark_drawn ) {
  232.       clear_right(edit);
  233.       edit->right_mark_drawn = 0;
  234.     }
  235.   }
  236.   draw_edit_cursor(edit, 0);
  237. }
  238.  
  239.  
  240. /*  Subroutine:    draw_edit_cursor
  241.  *  Xlib calls:    XDrawImageString()
  242.  */
  243. #ifdef ANSIC
  244. void draw_edit_cursor ( EditStruct *edit, int erase )
  245. #else
  246. void draw_edit_cursor ( edit, erase )
  247.      EditStruct *edit;
  248.      int erase;
  249. #endif
  250. {
  251.   int x;
  252.   GC gc;
  253.  
  254.   /*  Don't draw cursor if no mask bits  */
  255.   if( editor_mask == 0 )
  256.     return;
  257.   if( erase )
  258.     gc = set_text_gc(edit->font, edit->foreground, edit->background,
  259.              editor_func, editor_mask);
  260.   else
  261.     gc = set_text_gc(edit->font, edit->background, edit->foreground,
  262.              editor_func, editor_mask);
  263.   x = edit->pixlen[edit->active_position] -
  264.     edit->pixlen[edit->first_char_shown];
  265.   XDrawImageString(edit->display, edit->ID, gc, edit->x + x, edit->y,
  266.            &(edit->string[edit->active_position]), 1);
  267. }
  268.  
  269.  
  270. /*  Subroutine:    mark_left
  271.  *  Xlib calls:    XPutImage()
  272.  */
  273. #ifdef ANSIC
  274. static void mark_left ( EditStruct *edit, GC gc )
  275. #else
  276. static void mark_left ( edit, gc )
  277.      EditStruct *edit;
  278.      GC gc;
  279. #endif
  280. {
  281.   ximage.data = left_bits;
  282.   XPutImage(edit->display, edit->ID, gc, &ximage, 0, 0,
  283.         edit->x - MARK_LEFT, edit->y - MARK_Y, 8, 7);
  284. }
  285.  
  286.  
  287. /*  Subroutine:    clear_left
  288.  */
  289. #ifdef ANSIC
  290. static void clear_left ( EditStruct *edit )
  291. #else
  292. static void clear_left ( edit )
  293.      EditStruct *edit;
  294. #endif
  295. {
  296.   clear_area(edit, edit->x - MARK_LEFT, edit->y - MARK_Y, 8, 7);
  297. }
  298.  
  299.  
  300. /*  Subroutine:    mark_right
  301.  *  Xlib calls:    XPutImage()
  302.  */
  303. #ifdef ANSIC
  304. static void mark_right ( EditStruct *edit, GC gc )
  305. #else
  306. static void mark_right ( edit, gc )
  307.      EditStruct *edit;
  308.      GC gc;
  309. #endif
  310. {
  311.   ximage.data = right_bits;
  312.   XPutImage(edit->display, edit->ID, gc, &ximage, 0, 0,
  313.         edit->x + edit->max_pixlen + MARK_RIGHT, edit->y - MARK_Y, 8, 7);
  314. }
  315.  
  316.  
  317. /*  Subroutine:    clear_right
  318.  */
  319. #ifdef ANSIC
  320. static void clear_right ( EditStruct *edit )
  321. #else
  322. static void clear_right ( edit )
  323.      EditStruct *edit;
  324. #endif
  325. {
  326.   clear_area(edit, edit->x + edit->max_pixlen + MARK_RIGHT,
  327.          edit->y - MARK_Y, 8, 7);
  328. }
  329.  
  330.  
  331. /*  Subroutine:    clear_area
  332.  *  Purpose:    Clear area around edit string, mindful of mask in use
  333.  */
  334. #ifdef ANSIC
  335. static void clear_area ( EditStruct *edit,
  336.              int x, int y, int width, int height )
  337. #else
  338. static void clear_area ( edit, x, y, width, height )
  339.      EditStruct *edit;
  340.      int x, y, width, height;
  341. #endif
  342. {
  343.   GC gc;
  344.  
  345.   gc = set_text_gc(edit->font, edit->background, U_DONT_CARE,
  346.            editor_func, editor_mask);
  347.   XFillRectangle(edit->display, edit->ID, gc, x, y,
  348.          (unsigned int)width, (unsigned int)height);
  349. }
  350.